package com.wlanauth.service.manage.impl;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;

import com.wlanauth.core.exception.ServiceException;
import com.wlanauth.dao.manage.UserDao;
import com.wlanauth.dao.manage.UserHisDao;
import com.wlanauth.dao.radius.RadAcctDao;
import com.wlanauth.dao.radius.RadAcctHisDao;
import com.wlanauth.dao.radius.RadCheckDao;
import com.wlanauth.dao.radius.RadCheckHisDao;
import com.wlanauth.domain.manage.Operator;
import com.wlanauth.domain.manage.User;
import com.wlanauth.domain.manage.UserHis;
import com.wlanauth.domain.radius.RadAcct;
import com.wlanauth.domain.radius.RadAcctHis;
import com.wlanauth.domain.radius.RadCheck;
import com.wlanauth.domain.radius.RadCheckHis;
import com.wlanauth.service.common.impl.CommonServiceImpl;
import com.wlanauth.service.manage.UserService;

public class UserServiceImpl extends CommonServiceImpl<User> implements
		UserService {
	
	protected static Logger logger = Logger.getLogger(UserServiceImpl.class);
	
	private RadCheckDao radCheckDao;//认证
	private RadCheckHisDao radCheckHisDao;
	
	private RadAcctDao radAcctDao;//计费表

	private RadAcctHisDao radAcctHisDao;
	
	private UserHisDao userHisDao;//用户历史
	
	
	//private static Properties radiusProps = new Properties();
	private static List<RadCheck> radChecks = new ArrayList<RadCheck>();
	static {
		Properties radiusProps = new Properties();
		InputStream in = UserServiceImpl.class.getResourceAsStream("radius.properties");
		try {
			radiusProps.load(in);
			String[] radCheckIndexs = radiusProps.getProperty("radius.radCheck.index","").split("\\,");
			for(String indexStr:radCheckIndexs){
				//初始化属性
				RadCheck radCheck = new RadCheck();
				
				radCheck.setOp(radiusProps.getProperty("radCheck["+indexStr+"].op",":="));
				radCheck.setAttribute(radiusProps.getProperty("radCheck["+indexStr+"].attribute"));
				radCheck.setValue(radiusProps.getProperty("radCheck["+indexStr+"].value"));
				radChecks.add(radCheck);
				
			}
			
		} catch (Exception e) {
			throw new RuntimeException("加载radius.properties属性文件出错",e);
		} finally {
			try {
				if(in!= null) in.close();
			} catch (IOException e) {
				
			}
		}
	}
	
	public void setRadCheckHisDao(RadCheckHisDao radCheckHisDao) {
		this.radCheckHisDao = radCheckHisDao;
	}


	public void setRadAcctDao(RadAcctDao radAcctDao) {
		this.radAcctDao = radAcctDao;
	}


	
	public void setRadCheckDao(RadCheckDao radCheckDao) {
		this.radCheckDao = radCheckDao;
	}
	

	public void setRadAcctHisDao(RadAcctHisDao radAcctHisDao) {
		this.radAcctHisDao = radAcctHisDao;
	}


	public void setUserHisDao(UserHisDao userHisDao) {
		this.userHisDao = userHisDao;
	}


	@Override
	public void save(User t) throws ServiceException {
		try {
			//t.setPassword(MD5.);
			this.getDao().save(t);
			//计费
			for(RadCheck radCheck:radChecks){
				
				RadCheck temp = new RadCheck();
				BeanUtils.copyProperties(radCheck, temp);
				
				temp.setUsername(t.getBindIP());
				//加入最大流量限制属性
				if(temp.getAttribute().equals("Max-Traffic")){
					temp.setValue(BigDecimal.valueOf(1024*1024).multiply(BigDecimal.valueOf(t.getMaxOctets())).toString());
				}
				radCheckDao.save(temp);
			}
			
		} catch (Exception e){
			throw new ServiceException(e);
		}
	}

	

	@Override
	public void update(User t) throws ServiceException {
		try {
			this.getDao().update(t);
			
			List<RadCheck> radChecks = radCheckDao.getAllRadCheckByUsername(t.getUsername());
			//计费
			for(RadCheck temp:radChecks){
				//加入最大流量限制属性
				if(temp.getAttribute().equals("Max-Traffic")){
					temp.setValue(BigDecimal.valueOf(1024*1024).multiply(BigDecimal.valueOf(t.getMaxOctets())).toString());
					radCheckDao.update(temp);
					break ;
				}
				
			}
			
		} catch (Exception e){
			throw new ServiceException(e);
		}
	}


	@Override
	public void delete(User t) throws ServiceException {
		// TODO Auto-generated method stub
		User temp = this.getDao().get(t.getId());
		//删除计费
		List<RadAcct> radAccts = this.radAcctDao.getAllRadAcctByUsername(temp.getBindIP());
		this.radAcctDao.deleteAll(radAccts);
		//删除验证
		List<RadCheck> radChecks = radCheckDao.getAllRadCheckByUsername(temp.getBindIP());
		this.radCheckDao.deleteAll(radChecks);
		//删除用户
		this.getDao().delete(temp);
	}


	@Override
	public void deleteByKey(Serializable key) throws ServiceException {
		User user = new User();
		user.setId(key.toString());
		this.delete(user);
	}


	public User getByUsername(String username) throws ServiceException {
		return ((UserDao)this.getDao()).getByUsername(username);
	}


	public int transUserToHis(List<String> ids, Operator operator)
			throws ServiceException {
		try {
			int i = -1;
			for(String id:ids){
				logger.debug("开始 迁移用户至历史表[ID:"+id+"]");
				User user = this.get(id);
				if(user==null){
					logger.info("用户未找到，忽略[ID:"+id+"]");
					continue;
				}
				logger.debug("迁移计费信息");
				//迁移计费
				List<RadAcct> radAccts = this.radAcctDao.getAllRadAcctByUsername(user.getBindIP());
				this.transRadAcctsToHis(radAccts, operator);
				logger.debug("迁移认证信息");
				//迁移认证
				List<RadCheck> radChecks = radCheckDao.getAllRadCheckByUsername(user.getBindIP());
				this.transRadChecksToHis(radChecks,operator);
				
				UserHis his = new UserHis();
				BeanUtils.copyProperties(user, his);
				his.setCreateTime(new Date());
				his.setOperatorId(operator.getId());
				
				this.userHisDao.save(his);
				this.getDao().delete(user);
				logger.debug("完成 迁移用户至历史表[ID:"+id+"]");
				i++;
			}
			return i;
		} catch (Exception e){
			logger.error("迁移用户资料失败:"+e.getMessage(),e);
			throw new ServiceException(e);
		}
	}


	private void transRadChecksToHis(List<RadCheck> radChecks, Operator operator) {
		if(radChecks!=null){
			for(RadCheck radCheck:radChecks){
				RadCheckHis his = new RadCheckHis();
				BeanUtils.copyProperties(radCheck, his);
				his.setCreateTime(new Date());
				his.setOperatorId(operator.getId());
				this.radCheckHisDao.save(his);
				this.radCheckDao.delete(radCheck);
			}
		}
	}


	private void transRadAcctsToHis(List<RadAcct> radAccts, Operator operator) {
		if(radAccts!=null){
			for(RadAcct radAcct:radAccts){
				RadAcctHis his = new RadAcctHis();
				BeanUtils.copyProperties(radAcct, his);
				his.setCreateTime(new Date());
				his.setOperatorId(operator.getId());
				this.radAcctHisDao.save(his);
				this.radAcctDao.delete(radAcct);
			}
		}
	}


	public User getByBindIP(String bindIP) throws ServiceException {
		return ((UserDao)this.getDao()).getByBindIP(bindIP);
	}
	
}
